package org.chartsy.fi; import java.awt.Color; import java.awt.Graphics2D; import java.awt.Rectangle; import java.awt.Stroke; import java.text.DecimalFormat; import java.util.LinkedHashMap; import org.chartsy.main.ChartFrame; import org.chartsy.main.chart.Indicator; import org.chartsy.main.data.DataItem; import org.chartsy.main.data.Dataset; import org.chartsy.main.utils.DefaultPainter; import org.chartsy.main.utils.Range; import org.chartsy.main.utils.SerialVersion; import org.openide.nodes.AbstractNode; /** * * @author viorel.gheba */ public class ForceIndex extends Indicator { private static final long serialVersionUID = SerialVersion.APPVERSION; public static final String FI1 = "fi1"; public static final String FI2 = "fi2"; private IndicatorProperties properties; public ForceIndex() { super(); properties = new IndicatorProperties(); } public String getName() { return "FI"; } public String getLabel() { return properties.getLabel() + "(" + properties.getPeriod1() + ", " + properties.getPeriod2() + ")"; } public String getPaintedLabel(ChartFrame cf) { DecimalFormat df = new DecimalFormat("###,###"); double factor = getFactor(cf); return getLabel() + " x " + df.format((int)factor); } public Indicator newInstance() { return new ForceIndex(); } public LinkedHashMap getHTML(ChartFrame cf, int i) { LinkedHashMap ht = new LinkedHashMap(); DecimalFormat df = new DecimalFormat("###,###"); double factor = getFactor(cf); double[] values = getValues(cf, i); String[] labels = {"FI(" + properties.getPeriod1() + "):", "FI(" + properties.getPeriod2() + "):"}; ht.put(getLabel() + " x " + df.format((int)factor), " "); df = new DecimalFormat("#,##0.00"); if (values.length > 0) { Color[] colors = getColors(); for (int j = 0; j < values.length; j++) { ht.put(getFontHTML(colors[j], labels[j]), getFontHTML(colors[j], df.format(values[j]))); } } return ht; } public @Override Range getRange(ChartFrame cf) { Range range = super.getRange(cf); double factor = getFactor(cf); range = new Range(range.getLowerBound()/factor, range.getUpperBound()/factor); return range; } public void paint(Graphics2D g, ChartFrame cf, Rectangle bounds) { Dataset dataset1 = visibleDataset(cf, FI1); Dataset dataset2 = visibleDataset(cf, FI2); if (dataset1 != null && dataset2 != null) { if (maximized) { double factor = getFactor(cf); Range range = getRange(cf); DefaultPainter.line(g, cf, range, bounds, Dataset.DIV(dataset1, factor), properties.getColor1(), properties.getStroke1()); // paint line DefaultPainter.line(g, cf, range, bounds, Dataset.DIV(dataset2, factor), properties.getColor2(), properties.getStroke2()); // paint line } } } public void calculate() { Dataset initial = getDataset(); if (initial != null && !initial.isEmpty()) { int period1 = properties.getPeriod1(); int period2 = properties.getPeriod2(); Dataset dataset1 = getDataset(initial, period1); addDataset(FI1, dataset1); Dataset dataset2 = getDataset(initial, period2); addDataset(FI2, dataset2); } } public boolean hasZeroLine() { return false; } public boolean getZeroLineVisibility() { return false; } public Color getZeroLineColor() { return null; } public Stroke getZeroLineStroke() { return null; } public boolean hasDelimiters() { return false; } public boolean getDelimitersVisibility() { return false; } public double[] getDelimitersValues() { return new double[] {}; } public Color getDelimitersColor() { return null; } public Stroke getDelimitersStroke() { return null; } public Color[] getColors() { return new Color[] {properties.getColor1(), properties.getColor2()}; } public double[] getValues(ChartFrame cf) { Dataset dataset1 = visibleDataset(cf, FI1); Dataset dataset2 = visibleDataset(cf, FI2); double factor = getFactor(cf); if (dataset1 != null && dataset2 != null) return new double[] {dataset1.getLastClose()/factor, dataset2.getLastClose()/factor}; return new double[] {}; } public double[] getValues(ChartFrame cf, int i) { Dataset dataset1 = visibleDataset(cf, FI1); Dataset dataset2 = visibleDataset(cf, FI2); double factor = getFactor(cf); if (dataset1 != null && dataset2 != null) return new double[] {dataset1.getCloseAt(i)/factor, dataset2.getCloseAt(i)/factor}; return new double[] {}; } public boolean getMarkerVisibility() { return properties.getMarker(); } public AbstractNode getNode() { return new IndicatorNode(properties); } private Dataset getDataset(final Dataset initial, final int period) { int count = initial.getItemsCount(); Dataset d = Dataset.EMPTY(count); for (int i = 1; i < count; i++) { double fi = initial.getVolumeAt(i) * (initial.getCloseAt(i) - initial.getCloseAt(i-1)); d.setDataItem(i, new DataItem(initial.getTimeAt(i), fi)); } return Dataset.SMA(d, period); } private double getFactor(ChartFrame cf) { Dataset dataset1 = visibleDataset(cf, FI1); Dataset dataset2 = visibleDataset(cf, FI2); if (dataset1 != null && dataset2 != null) { Range range = new Range(dataset1.getMin(Dataset.CLOSE), dataset1.getMax(Dataset.CLOSE)); range = Range.combine(range, new Range(dataset2.getMin(Dataset.CLOSE), dataset2.getMax(Dataset.CLOSE))); int max = Integer.toString((int)Math.round(range.getUpperBound())).length() - 1; int min = Integer.toString((int)Math.round(range.getLowerBound())).length() - 1; int scale = Math.min(max, min); if (scale > 1) scale--; return Math.pow(10, scale); } return 1; } }